package ru.sstu.renju.players;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ru.sstu.renju.core.CellType;
import ru.sstu.renju.core.Game;
import ru.sstu.renju.core.Move;
import ru.sstu.renju.core.Player;
import ru.sstu.renju.core.Row;
import ru.sstu.renju.core.RowUtil;

/**
 * {@code SimplePlayer} class is {@link Player} implementation with
 * artificial intelligence.
 *
 * @author Denis_Murashev
 */
public class SimplePlayer implements Player {

	private static final int[] SAME_WEIGHTS = {0, 3, 30, 300, 3000};

	private static final int[] OTHER_WEIGHTS = {0, 1, 10, 100, 1000};

	@Override
	public String toString() {
		return "Simple";
	}

	@Override
	public Move doMove(Game game, CellType type) {
		if (game.getMoveCount() == 0) {
			return new Move(Game.SIZE / 2, Game.SIZE / 2);
		}
		int best = -1;
		List<Move> moves = new ArrayList<Move>();
		for (int i = 0; i < Game.SIZE; i++) {
			for (int j = 0; j < Game.SIZE; j++) {
				if (game.isFreeCell(i, j)) {
					int weight = getWeight(game, i, j, type);
					if (weight > best) {
						best = weight;
						moves.clear();
						moves.add(new Move(i, j));
					} else if (weight == best) {
						moves.add(new Move(i, j));
					}
				}
			}
		}
		Collections.shuffle(moves);
		return moves.get(0);
	}

	private int getWeight(Game game, int i, int j, CellType type) {
		int weight = 0;
		for (Row row : RowUtil.longList(i, j)) {
			weight += getRowWeight(game, row, type);
		}
		return weight;
	}

	private int getRowWeight(Game game, Row row, CellType type) {
		int same = 0;
		int other = 0;
		Iterator<CellType> iterator = game.rowIterator(row);
		while (iterator.hasNext()) {
			CellType cell = iterator.next();
			if (cell == type) {
				if (other != 0) {
					return 0;
				}
				same++;
			} else if (cell != null) {
				if (same != 0) {
					return 0;
				}
				other++;
			}
		}
		if (same > 0) {
			return SAME_WEIGHTS[same];
		}
		return OTHER_WEIGHTS[other];
	}
}
